package com.stormragetech.arthas.serialize.convertor;

import com.stormragetech.arthas.common.constant.Constant;
import com.stormragetech.arthas.common.exception.ArthasException;
import com.stormragetech.arthas.common.util.Assert;
import lombok.extern.log4j.Log4j2;

import java.math.BigDecimal;

/**
 * description: primitive convertor
 *
 * @author: Xue Bin
 * @version: 1.0.0-SNAPSHOT
 */
@Log4j2
public class PrimitiveConvertor<T> implements Convertor {

    private final String v;
    private final Class<T> c;

    private T t;

    public PrimitiveConvertor(String v, Class<T> c) throws ArthasException {
        Assert.notNull(v, "the value can not be null !!!");
        Assert.notNull(c, "the target type can not be null !!!");
        this.v = v;
        this.c = c;
        conv();
    }

    @SuppressWarnings("unchecked")
    private void conv() throws ArthasException {
        if (isInt()) {
            t = (T) convToInt();
        } else if (isLong()) {
            t = (T) convToLong();
        } else if (isDouble()) {
            t = (T) convToDouble();
        } else if (isBoolean()) {
            t = (T) convToBoolean();
        } else if (isDecimal()) {
            t = (T) convToDecimal();
        } else if (isString()) {
            t = (T) v;
        } else {
            throw new ArthasException(Constant.CONV_ERR_CODE, Constant.CONV_NOT_PRIMITIVE, ArthasException.APP_ERR);
        }

    }

    private boolean isInt() throws ArthasException {
        return c.equals(int.class) || c.equals(Integer.class);
    }

    private boolean isLong() throws ArthasException {
        return c.equals(long.class) || c.equals(Long.class);
    }

    private boolean isDouble() throws ArthasException {
        return c.equals(double.class) || c.equals(Double.class);
    }

    private boolean isBoolean() throws ArthasException {
        return c.equals(boolean.class) || c.equals(Boolean.class);
    }

    private boolean isDecimal() throws ArthasException {
        return c.equals(BigDecimal.class);
    }


    private boolean isString() throws ArthasException {
        return c.equals(String.class);
    }

    private Object convToInt() throws ArthasException {
        return Integer.valueOf(v);
    }

    private Object convToLong() throws ArthasException {
        return Long.valueOf(v);
    }

    private Object convToDouble() throws ArthasException {
        return Double.valueOf(v);
    }

    private Object convToBoolean() throws ArthasException {
        return Boolean.valueOf(v);
    }

    private Object convToDecimal() throws ArthasException {
        return new BigDecimal(v);
    }

    @Override
    public T convert() throws ArthasException {
        return t;
    }


}
